package jp.co.redfox.archclub.poker.hand;

import java.util.EnumSet;

import jp.co.redfox.archclub.poker.Hand;
import jp.co.redfox.archclub.poker.hand.comparable.FiveKindOfCardsComparator;
import jp.co.redfox.archclub.poker.hand.comparable.FlashComparator;
import jp.co.redfox.archclub.poker.hand.comparable.FourKindOfCardsComparator;
import jp.co.redfox.archclub.poker.hand.comparable.FullHouseComparator;
import jp.co.redfox.archclub.poker.hand.comparable.HandComparator;
import jp.co.redfox.archclub.poker.hand.comparable.HiCardComparator;
import jp.co.redfox.archclub.poker.hand.comparable.OnePairComparator;
import jp.co.redfox.archclub.poker.hand.comparable.RoyalStraightFlashComparator;
import jp.co.redfox.archclub.poker.hand.comparable.StraightComparator;
import jp.co.redfox.archclub.poker.hand.comparable.StraightFlashComparator;
import jp.co.redfox.archclub.poker.hand.comparable.ThreeKindOfCardsComparator;
import jp.co.redfox.archclub.poker.hand.comparable.TwoPairComparator;

public enum KindOfHand {
    HiCard(new HiCardComparator(), new HiCard()),
    OnePair(new OnePairComparator(), new NumOfKind(2)),
    TwoPair(new TwoPairComparator(), new NumOfKind(2,2)),
    ThreeKindOfCards(new ThreeKindOfCardsComparator(), new NumOfKind(3)),
    Straight(new StraightComparator(), new Straight()),
    Flash(new FlashComparator(), new Flash()),
    FullHouse(new FullHouseComparator(), new NumOfKind(2,3)),
    FourKindOfCards(new FourKindOfCardsComparator(), new NumOfKind(4)),
    FiveKindOfCards(new FiveKindOfCardsComparator(), new NumOfKind(5)),
    StraightFlash(new StraightFlashComparator(), new Straight(), new Flash()),
    RoyalStraightFlash(new RoyalStraightFlashComparator(), new RoyalStraight(), new Flash());
    
    private HandRestriction[] restrictions;
    private HandComparator handComparator;
    private KindOfHand(HandComparator handComparator, HandRestriction... restrictions){
        this.restrictions = restrictions;
        this.handComparator = handComparator;
    }
    public boolean matches(Hand hand){
        for (HandRestriction restriction : restrictions)
            if( ! restriction.matches(hand))
                return false;
        return true;
    }

    public static KindOfHand judgeHand(Hand hand){
        KindOfHand ret = null;
        for (KindOfHand koh : EnumSet.allOf(KindOfHand.class)) {
            if (koh.matches(hand))
                    ret = koh;
        }
        return ret;
    }
    
    public int compare(Hand myHand, Hand rivalHand) {
        return this.handComparator.compare(myHand, rivalHand);
    }
}
